use crate::{BandwidthLevel, BandwidthStatus};
use futures_util::StreamExt;
use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use tauri::{AppHandle, Emitter};
use tokio::time;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RealtimeData {
    pub timestamp: u64,
    pub speed_mbps: f64,
    pub speed_mb_per_sec: f64,
    pub bytes_consumed: u64,
    pub peak_speed: f64,
    pub avg_speed: f64,
    pub duration_seconds: u64,
    pub active_connections: usize,
}

pub struct BandwidthController {
    current_level: BandwidthLevel,
    bytes_consumed: Arc<AtomicU64>,
    start_time: Option<Instant>,
    current_speed_mbps: Arc<std::sync::atomic::AtomicU64>,
    is_active: bool,
    task_handles: Vec<tokio::task::JoinHandle<()>>,
    app_handle: Option<AppHandle>,
    active_connections: Arc<std::sync::atomic::AtomicUsize>,
}

impl Default for BandwidthController {
    fn default() -> Self {
        Self {
            current_level: BandwidthLevel::Off,
            bytes_consumed: Arc::new(AtomicU64::new(0)),
            start_time: None,
            current_speed_mbps: Arc::new(std::sync::atomic::AtomicU64::new(0)),
            is_active: false,
            task_handles: Vec::new(),
            app_handle: None,
            active_connections: Arc::new(std::sync::atomic::AtomicUsize::new(0)),
        }
    }
}

impl BandwidthController {
    pub fn set_app_handle(&mut self, app_handle: AppHandle) {
        self.app_handle = Some(app_handle);
    }

    pub async fn start(&mut self, level: BandwidthLevel) -> Result<(), Box<dyn std::error::Error>> {
        // 先停止之前的任务
        self.stop().await;

        self.current_level = level.clone();
        self.start_time = Some(Instant::now());
        self.is_active = true;
        self.bytes_consumed.store(0, Ordering::SeqCst);

        match level {
            BandwidthLevel::Off => {
                // 不做任何操作
            }
            _ => {
                let (target_speed_mbps, connections) = self.get_level_config(&level);

                // 启动速度监控任务
                let bytes_consumed_monitor = Arc::clone(&self.bytes_consumed);
                let current_speed_monitor = Arc::clone(&self.current_speed_mbps);
                let active_connections_monitor = Arc::clone(&self.active_connections);
                let app_handle_monitor = self.app_handle.clone();
                let start_time_monitor = Instant::now();

                let monitor_handle = tokio::spawn(async move {
                    speed_monitor_task(
                        bytes_consumed_monitor,
                        current_speed_monitor,
                        active_connections_monitor,
                        app_handle_monitor,
                        start_time_monitor,
                    )
                    .await;
                });
                self.task_handles.push(monitor_handle);

                // 启动下载任务（占70%带宽）
                let download_connections = connections * 7 / 10;
                let download_speed = target_speed_mbps * 0.7;
                for i in 0..download_connections {
                    let bytes_consumed = Arc::clone(&self.bytes_consumed);
                    let active_connections = Arc::clone(&self.active_connections);
                    let speed_per_connection = download_speed / download_connections as f64;

                    let handle = tokio::spawn(async move {
                        download_task(bytes_consumed, active_connections, speed_per_connection, i)
                            .await;
                    });

                    self.task_handles.push(handle);
                }

                // 启动上传任务（占30%带宽）
                let upload_connections = connections - download_connections;
                let upload_speed = target_speed_mbps * 0.3;
                if upload_connections > 0 {
                    for i in 0..upload_connections {
                        let bytes_consumed = Arc::clone(&self.bytes_consumed);
                        let active_connections = Arc::clone(&self.active_connections);
                        let speed_per_connection = upload_speed / upload_connections as f64;

                        let handle = tokio::spawn(async move {
                            upload_task(
                                bytes_consumed,
                                active_connections,
                                speed_per_connection,
                                i + 1000,
                            )
                            .await;
                        });

                        self.task_handles.push(handle);
                    }
                }

                println!("╔══════════════════ 🚀 带宽控制器启动 ══════════════════╗");
                println!(
                    "║ 📊 目标总速度: {:.1} Mbps ({:.1} MB/s)                     ║",
                    target_speed_mbps,
                    target_speed_mbps / 8.0
                );
                println!(
                    "║ 🔽 下载: {} 连接 × {:.1} Mbps = {:.1} Mbps              ║",
                    download_connections,
                    download_speed / download_connections as f64,
                    download_speed
                );
                println!(
                    "║ 🔼 上传: {} 连接 × {:.1} Mbps = {:.1} Mbps              ║",
                    upload_connections,
                    if upload_connections > 0 {
                        upload_speed / upload_connections as f64
                    } else {
                        0.0
                    },
                    upload_speed
                );
                println!(
                    "║ ⚙️  等级: {:?}                                        ║",
                    level
                );
                println!("╚═══════════════════════════════════════════════════════╝");
                println!();
            }
        }

        Ok(())
    }

    pub async fn stop(&mut self) {
        self.is_active = false;

        // 取消所有任务
        for handle in self.task_handles.drain(..) {
            handle.abort();
        }

        self.current_level = BandwidthLevel::Off;
        self.current_speed_mbps.store(0, Ordering::SeqCst);
        self.active_connections.store(0, Ordering::SeqCst);

        println!("已停止所有带宽占用任务");
    }

    pub fn get_status(&self, is_running: bool) -> BandwidthStatus {
        let duration_seconds = if let Some(start_time) = self.start_time {
            start_time.elapsed().as_secs()
        } else {
            0
        };

        let speed_bits = self.current_speed_mbps.load(Ordering::SeqCst);
        let speed_mbps = f64::from_bits(speed_bits);

        BandwidthStatus {
            level: self.current_level.clone(),
            is_running: is_running && self.is_active,
            bytes_consumed: self.bytes_consumed.load(Ordering::SeqCst),
            duration_seconds,
            current_speed_mbps: speed_mbps,
        }
    }

    fn get_level_config(&self, level: &BandwidthLevel) -> (f64, usize) {
        match level {
            BandwidthLevel::Off => (0.0, 0),
            BandwidthLevel::Micro => (5.0, 2),   // 5 Mbps, 2个连接
            BandwidthLevel::Mini => (15.0, 3),   // 15 Mbps, 3个连接
            BandwidthLevel::Low => (30.0, 5),    // 30 Mbps, 5个连接
            BandwidthLevel::Medium => (50.0, 8), // 50 Mbps, 8个连接
            BandwidthLevel::High => (75.0, 10),  // 75 Mbps, 10个连接
            BandwidthLevel::Turbo => (100.0, 12), // 100 Mbps, 12个连接
            BandwidthLevel::Ultra => (150.0, 16), // 150 Mbps, 16个连接
            BandwidthLevel::Extreme => (200.0, 20), // 200 Mbps, 20个连接
        }
    }
}

// 速度监控任务
async fn speed_monitor_task(
    bytes_consumed: Arc<AtomicU64>,
    current_speed: Arc<std::sync::atomic::AtomicU64>,
    active_connections: Arc<std::sync::atomic::AtomicUsize>,
    app_handle: Option<AppHandle>,
    start_time: Instant,
) {
    let mut last_bytes = 0u64;
    let mut last_time = Instant::now();
    let mut peak_speed_mbps = 0.0;
    let mut total_sessions = 0u64;

    let mut interval = time::interval(Duration::from_secs(1));

    loop {
        interval.tick().await;
        total_sessions += 1;

        let now = Instant::now();
        let current_bytes = bytes_consumed.load(Ordering::SeqCst);
        let time_diff = now.duration_since(last_time).as_secs_f64();

        if time_diff >= 0.8 {
            // 稍微提前一点更新，确保及时性
            let bytes_diff = if current_bytes > last_bytes {
                current_bytes - last_bytes
            } else {
                0
            };

            // 计算多种速度单位
            let speed_mbps = (bytes_diff as f64 * 8.0) / (time_diff * 1_000_000.0);
            let speed_mb_per_sec = bytes_diff as f64 / (time_diff * 1_000_000.0); // MB/s
            let speed_kb_per_sec = bytes_diff as f64 / (time_diff * 1_000.0); // KB/s

            // 更新峰值速度
            if speed_mbps > peak_speed_mbps {
                peak_speed_mbps = speed_mbps;
            }

            // 计算平均速度
            let total_time = now.duration_since(start_time).as_secs_f64();
            let avg_speed_mbps = if total_time > 0.0 {
                (current_bytes as f64 * 8.0) / (total_time * 1_000_000.0)
            } else {
                0.0
            };

            current_speed.store(speed_mbps.to_bits(), Ordering::SeqCst);

            // 发送实时数据事件到前端
            if let Some(app) = &app_handle {
                let realtime_data = RealtimeData {
                    timestamp: SystemTime::now()
                        .duration_since(UNIX_EPOCH)
                        .unwrap_or(Duration::from_secs(0))
                        .as_millis() as u64,
                    speed_mbps,
                    speed_mb_per_sec,
                    bytes_consumed: current_bytes,
                    peak_speed: peak_speed_mbps,
                    avg_speed: avg_speed_mbps,
                    duration_seconds: total_time as u64,
                    active_connections: active_connections.load(Ordering::SeqCst),
                };

                if let Err(e) = app.emit("realtime-bandwidth-data", &realtime_data) {
                    eprintln!("Failed to emit realtime data: {}", e);
                }
            }

            // 丰富的实时显示信息
            println!("╭─────────────────── 流量监控 ───────────────────╮");
            println!(
                "│ 📊 实时速度: {:.2} Mbps ({:.2} MB/s)             │",
                speed_mbps, speed_mb_per_sec
            );
            println!(
                "│ 📈 峰值速度: {:.2} Mbps                         │",
                peak_speed_mbps
            );
            println!(
                "│ 📉 平均速度: {:.2} Mbps                         │",
                avg_speed_mbps
            );
            println!(
                "│ 💾 瞬时流量: {:.2} KB/s                         │",
                speed_kb_per_sec
            );
            println!(
                "│ 📦 已消耗: {:.2} MB ({:.2} GB)                 │",
                current_bytes as f64 / 1_000_000.0,
                current_bytes as f64 / 1_000_000_000.0
            );
            println!(
                "│ ⏱️  运行时长: {:.0} 秒 ({} 次统计)               │",
                total_time, total_sessions
            );
            println!(
                "│ 🔗 活跃连接: {} 个                             │",
                active_connections.load(Ordering::SeqCst)
            );

            // 根据速度显示不同的状态指示器
            let status_indicator = if speed_mbps >= 50.0 {
                "🔥 极速"
            } else if speed_mbps >= 20.0 {
                "⚡ 高速"
            } else if speed_mbps >= 5.0 {
                "📶 中速"
            } else if speed_mbps >= 1.0 {
                "🐌 低速"
            } else {
                "⏸️  待机"
            };

            println!(
                "│ 🚀 状态: {}                               │",
                status_indicator
            );
            println!("╰─────────────────────────────────────────────────╯");
            println!();

            last_bytes = current_bytes;
            last_time = now;
        }
    }
}

// 下载任务
async fn download_task(
    bytes_consumed: Arc<AtomicU64>,
    active_connections: Arc<std::sync::atomic::AtomicUsize>,
    target_speed_mbps: f64,
    task_id: usize,
) {
    let client = reqwest::Client::new();

    // 使用国内高速镜像下载URL
    let download_urls = vec![
        "https://registry.npmmirror.com/react/18.2.0/react-18.2.0.tgz", // 淘宝NPM镜像
        "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/source/r/requests/requests-2.31.0.tar.gz", // 清华PyPI镜像
        "https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/docker-ce-20.10.21-3.el8.x86_64.rpm", // 阿里云Docker镜像
        "https://cdn.npm.taobao.org/packages/typescript/4.9.5/typescript-4.9.5.tgz", // 淘宝TypeScript
        "https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.13-3.5.0/kafka_2.13-3.5.0.tgz", // 清华Apache镜像
        "https://mirrors.163.com/maven/central/org/springframework/spring-core/5.3.23/spring-core-5.3.23.jar", // 网易Maven镜像
        "https://mirrors.aliyun.com/centos/8-stream/BaseOS/x86_64/os/Packages/kernel-4.18.0-448.el8.x86_64.rpm", // 阿里云CentOS
        "https://registry.npmmirror.com/vue/3.3.4/vue-3.3.4.tgz", // 淘宝Vue镜像
        "https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-12.2.0/gcc-12.2.0.tar.gz", // 清华GNU镜像
        "https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js", // jsDelivr CDN
    ];

    let target_bytes_per_second = (target_speed_mbps * 1_000_000.0 / 8.0) as u64;
    let mut url_index = task_id;
    let mut task_bytes_consumed = 0u64;
    let task_start_time = Instant::now();

    println!(
        "🔽 下载任务 {} 启动 | 目标: {:.2} Mbps ({:.2} MB/s)",
        task_id,
        target_speed_mbps,
        target_speed_mbps / 8.0
    );

    loop {
        let url = &download_urls[url_index % download_urls.len()];
        url_index += 1;

        // 增加活跃连接计数
        active_connections.fetch_add(1, Ordering::SeqCst);

        match client
            .get(*url)
            .header("User-Agent", "BandwidthController/1.0")
            .timeout(Duration::from_secs(30))
            .send()
            .await
        {
            Ok(response) => {
                let file_name = url.split('/').last().unwrap_or("unknown");
                let content_length = response
                    .headers()
                    .get("content-length")
                    .and_then(|v| v.to_str().ok())
                    .and_then(|v| v.parse::<u64>().ok())
                    .unwrap_or(0);

                let file_size_mb = content_length as f64 / 1_000_000.0;
                let content_type = response
                    .headers()
                    .get("content-type")
                    .and_then(|v| v.to_str().ok())
                    .unwrap_or("unknown");

                println!("   📁 任务 {} 开始下载:", task_id);
                println!("      └─ 文件: {}", file_name);
                println!(
                    "      └─ 大小: {:.2} MB ({} 字节)",
                    file_size_mb, content_length
                );
                println!("      └─ 类型: {}", content_type);
                println!(
                    "      └─ 来源: {}",
                    url.split("//")
                        .nth(1)
                        .unwrap_or(url)
                        .split("/")
                        .next()
                        .unwrap_or("unknown")
                );

                let mut stream = response.bytes_stream();
                let mut bytes_this_second = 0u64;
                let mut last_report_time = Instant::now();
                let mut chunk_count = 0u64;
                let mut second_start_time = Instant::now();

                while let Some(chunk_result) = stream.next().await {
                    match chunk_result {
                        Ok(chunk) => {
                            let chunk_size = chunk.len() as u64;

                            // 检查当前秒内是否已经达到速度限制
                            if bytes_this_second + chunk_size > target_bytes_per_second {
                                let elapsed = second_start_time.elapsed();
                                if elapsed < Duration::from_secs(1) {
                                    let sleep_time = Duration::from_secs(1) - elapsed;
                                    time::sleep(sleep_time).await;
                                }
                                // 重置计数器和时间
                                bytes_this_second = 0;
                                second_start_time = Instant::now();
                            }

                            bytes_consumed.fetch_add(chunk_size, Ordering::SeqCst);
                            bytes_this_second += chunk_size;
                            task_bytes_consumed += chunk_size;
                            chunk_count += 1;

                            // 每5秒报告一次任务级别的统计
                            if last_report_time.elapsed() >= Duration::from_secs(5) {
                                let task_duration = task_start_time.elapsed().as_secs_f64();
                                let task_avg_speed = if task_duration > 0.0 {
                                    (task_bytes_consumed as f64 * 8.0)
                                        / (task_duration * 1_000_000.0)
                                } else {
                                    0.0
                                };

                                println!("   ⚡ 任务 {} | 平均: {:.2} Mbps | 已下载: {:.1} MB | 块数: {}", 
                                    task_id, task_avg_speed, task_bytes_consumed as f64 / 1_000_000.0, chunk_count);

                                last_report_time = Instant::now();
                            }

                            // 精确的速度控制 - 二次检查
                            if bytes_this_second >= target_bytes_per_second {
                                let elapsed = second_start_time.elapsed();
                                if elapsed < Duration::from_secs(1) {
                                    let sleep_time = Duration::from_secs(1) - elapsed;
                                    time::sleep(sleep_time).await;
                                }
                                // 重置计数器和时间
                                bytes_this_second = 0;
                                second_start_time = Instant::now();
                            }
                        }
                        Err(_) => break,
                    }
                }

                println!(
                    "   ✅ 任务 {} 完成下载: {} ({:.2} MB)",
                    task_id, file_name, file_size_mb
                );
            }
            Err(e) => {
                println!("下载任务 {} 失败: {}", task_id, e);
                time::sleep(Duration::from_secs(1)).await;
            }
        }

        // 减少活跃连接计数
        active_connections.fetch_sub(1, Ordering::SeqCst);

        // 短暂延迟后重新开始
        time::sleep(Duration::from_millis(100)).await;
    }
}

// 上传任务
async fn upload_task(
    bytes_consumed: Arc<AtomicU64>,
    active_connections: Arc<std::sync::atomic::AtomicUsize>,
    target_speed_mbps: f64,
    task_id: usize,
) {
    let client = reqwest::Client::new();

    // 创建上传数据
    let chunk_size = 1024 * 1024; // 1MB chunks
    let upload_data = vec![0u8; chunk_size];

    let target_bytes_per_second = (target_speed_mbps * 1_000_000.0 / 8.0) as u64;
    let mut task_bytes_uploaded = 0u64;
    let task_start_time = Instant::now();
    let mut last_report_time = Instant::now();
    let mut upload_count = 0u64;

    println!(
        "🔼 上传任务 {} 启动 | 目标: {:.2} Mbps ({:.2} MB/s)",
        task_id,
        target_speed_mbps,
        target_speed_mbps / 8.0
    );

    loop {
        let mut bytes_this_second = 0u64;
        let second_start_time = Instant::now();

        // 持续上传数据到测试接口，直到达到每秒目标速度
        while bytes_this_second < target_bytes_per_second {
            let remaining_bytes = target_bytes_per_second - bytes_this_second;
            let chunk_to_send = std::cmp::min(chunk_size as u64, remaining_bytes) as usize;
            let data_to_send = upload_data[..chunk_to_send].to_vec();

            // 使用支持POST的测试接口
            let upload_urls = vec![
                "https://httpbin.org/post",                   // httpbin POST接口
                "https://httpbin.org/anything",               // httpbin任意方法接口
                "https://postman-echo.com/post",              // Postman Echo POST
                "https://reqres.in/api/users",                // ReqRes POST接口
                "https://jsonplaceholder.typicode.com/posts", // JSONPlaceholder POST
                "https://httpbin.org/drain",                  // httpbin drain接口(用于上传测试)
            ];

            let url = &upload_urls[task_id % upload_urls.len()];
            let endpoint = url.split('/').last().unwrap_or("unknown");

            // 增加活跃连接计数
            active_connections.fetch_add(1, Ordering::SeqCst);

            match client
                .post(*url)
                .header("Content-Type", "application/octet-stream")
                .header("User-Agent", "BandwidthController/1.0")
                .body(data_to_send)
                .timeout(Duration::from_secs(10))
                .send()
                .await
            {
                Ok(_) => {
                    bytes_consumed.fetch_add(chunk_to_send as u64, Ordering::SeqCst);
                    bytes_this_second += chunk_to_send as u64;
                    task_bytes_uploaded += chunk_to_send as u64;
                    upload_count += 1;

                    // 每10次上传报告一次统计
                    if upload_count % 10 == 0
                        || last_report_time.elapsed() >= Duration::from_secs(8)
                    {
                        let task_duration = task_start_time.elapsed().as_secs_f64();
                        let task_avg_speed = if task_duration > 0.0 {
                            (task_bytes_uploaded as f64 * 8.0) / (task_duration * 1_000_000.0)
                        } else {
                            0.0
                        };

                        println!(
                            "   ⬆️  任务 {} -> {} | 平均: {:.2} Mbps | 已上传: {:.1} MB | 次数: {}",
                            task_id,
                            endpoint,
                            task_avg_speed,
                            task_bytes_uploaded as f64 / 1_000_000.0,
                            upload_count
                        );

                        last_report_time = Instant::now();
                    }
                }
                Err(e) => {
                    println!("   ❌ 上传任务 {} 失败 -> {}: {}", task_id, endpoint, e);
                    // 减少活跃连接计数
                    active_connections.fetch_sub(1, Ordering::SeqCst);
                    time::sleep(Duration::from_secs(1)).await;
                    break;
                }
            }

            // 减少活跃连接计数（成功情况）
            active_connections.fetch_sub(1, Ordering::SeqCst);
        }

        // 确保每秒循环一次
        let elapsed = second_start_time.elapsed();
        if elapsed < Duration::from_secs(1) {
            time::sleep(Duration::from_secs(1) - elapsed).await;
        }

        // 每轮结束后的统计
        let actual_speed =
            (bytes_this_second as f64 * 8.0) / second_start_time.elapsed().as_secs_f64().max(1.0);
        println!(
            "   📊 任务 {} 本轮: {:.2} MB 用时 {:.1}s 实际速度 {:.2} Mbps",
            task_id,
            bytes_this_second as f64 / 1_000_000.0,
            second_start_time.elapsed().as_secs_f64(),
            actual_speed
        );
    }
}
